package com.ruoyi.contract.controller;

import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.core.page.TableSupport;
import com.ruoyi.common.utils.PageUtils;
import com.ruoyi.contract.domain.ContractAppendices;
import com.ruoyi.contract.domain.contractVo.ContractAllPartyVo;
import com.ruoyi.contract.domain.contractVo.ContractAllRelevantVo;
import com.ruoyi.contract.tools.FileUtil;
import com.ruoyi.system.service.ISysUserService;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.contract.domain.Contract;
import com.ruoyi.contract.service.IContractService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

/**
 * 合同Controller
 * 
 * @author ruoyi
 * @date 2024-10-18
 */
@RestController
@RequestMapping("/contract/Contract")
public class ContractController extends BaseController
{
    @Autowired
    private IContractService contractService;

    @Autowired
    private ISysUserService userService;

    /**
     * 查询合同列表
     */
    @PreAuthorize("@ss.hasPermi('contract:Contract:list')")
    @GetMapping("/list")
    public TableDataInfo list(Contract contract, Integer pageNum, Integer pageSize)
    {
//        if (pageNum!=null && pageSize!=null){
//            startPage();
//        }
        List<ContractAllPartyVo> list = contractService.selectContractList(contract);
        TableDataInfo rspData = new TableDataInfo();
        rspData.setTotal(list.size());
        if (pageNum!=null && pageSize!=null){
            int start = (pageNum-1)*pageSize;
            int end = (pageNum-1)*pageSize+pageSize;
            if (end > list.size())
                end = list.size();
            list = list.subList(start,end);
        }
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setMsg("查询成功");
        rspData.setRows(list);
        return rspData;
    }


    /**
     * 导出合同列表
     */
    @PreAuthorize("@ss.hasPermi('contract:Contract:export')")
    @Log(title = "合同", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
//    public void export(HttpServletResponse response, Contract contract)
    public void export(HttpServletResponse response, @RequestBody(required = false) Long[] contractIds)
    {
        List<Contract> list = new ArrayList<Contract>();
        if(contractIds == null || contractIds.length == 0){
            Contract contract = new Contract();
            for (ContractAllPartyVo contractAllPartyVo: contractService.selectContractList(contract)){
                list.add(contractAllPartyVo.getContract());
            }
        }
        else{
            list = contractService.selectContractListByContractIds(contractIds);
        }

        // 序号
        AtomicInteger index = new AtomicInteger(1);
        list.forEach(item->{
            item.setIndex(index.getAndIncrement());  // 设置序号
            item.setCustomColumn(item.getCustomColumn());  // 设置合同状态
            String UserDepartment = userService.selectUserById(item.getAddUserId()).getDept().getDeptName();//获取部门名称
            item.setUserDepartmentString(item.getAddUserName() + " " +UserDepartment);//拼接创建人部门+创建人名称
        });
        ExcelUtil<Contract> util = new ExcelUtil<Contract>(Contract.class);
        util.exportExcel(response, list, "合同数据");
    }

    /**
     * 获取合同详细信息
     */
    @PreAuthorize("@ss.hasPermi('contract:Contract:query')")
    @GetMapping(value = "/{contractId}")
    public AjaxResult getInfo(@PathVariable("contractId") Long contractId)
    {
        return success(contractService.selectContractByContractId(contractId));
    }

    /**
     * 新增合同
     */
    @PreAuthorize("@ss.hasPermi('contract:Contract:add')")
    @Log(title = "合同", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody ContractAllRelevantVo contractAllRelevantVo)
    {
        return toAjax(contractService.insertContract(contractAllRelevantVo));
    }

    /**
     * 修改合同
     */
    @PreAuthorize("@ss.hasPermi('contract:Contract:edit')")
    @Log(title = "合同", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody ContractAllRelevantVo contractAllRelevantVo)
    {
        return toAjax(contractService.updateContract(contractAllRelevantVo));
    }

    /**
     * 删除合同
     */
    @PreAuthorize("@ss.hasPermi('contract:Contract:remove')")
    @Log(title = "合同", businessType = BusinessType.DELETE)
	@DeleteMapping("/{contractIds}")
    public AjaxResult remove(@PathVariable Long[] contractIds)
    {
        return toAjax(contractService.deleteContractByContractIds(contractIds));
    }

    /**
     * 批量下载合同
     */
    @PreAuthorize("@ss.hasPermi('contract:Contract:export')")
    @Log(title = "合同", businessType = BusinessType.EXPORT)
    @PostMapping("/download")
    public void downloadContractFiles(HttpServletResponse response, @RequestBody Long[] contractIds) throws IOException {
        // 创建临时文件夹
        String tempDirPath = System.getProperty("java.io.tmpdir") + File.separator + "contracts";
        File tempDir = new File(tempDirPath);
        if (!tempDir.exists()) {
            tempDir.mkdirs();
        }

        // 查询合同信息
        List<ContractAllRelevantVo> contractAllRelevantVoList = new ArrayList<>();
        for (Long contractId : contractIds) {
            contractAllRelevantVoList.add(contractService.selectContractByContractId(contractId));
        }

        String zipFolderPath = tempDirPath + File.separator + "合同";
        FileUtil.createFolder(zipFolderPath); // 创建名为“合同”的父文件夹

        // 在合同文件夹下创建以合同公司为名的子文件夹，再将其合同文件、合同附件文件放入其中
        for (ContractAllRelevantVo contractAllRelevantVo : contractAllRelevantVoList) {
            String subFolderPath = FileUtil.createSubFolder(zipFolderPath, contractAllRelevantVo.getContract().getBelongingCompanyName()); // 以公司为名创建子文件夹
            File sourceFile = new File(RuoYiConfig.getProfile() + contractAllRelevantVo.getContract().getPdfAddress().replaceFirst("^/profile", ""));
            FileUtil.copyFileToFolder(sourceFile, subFolderPath); // 添加合同文件到子文件夹中

            for (ContractAppendices contractAppendices : contractAllRelevantVo.getContractAppendicesList()) {
                File appendixFile = new File(RuoYiConfig.getProfile() + contractAppendices.getPdfAddress().replaceFirst("^/profile", ""));
                FileUtil.copyFileToFolder(appendixFile, subFolderPath); // 添加合同附件文件到子文件夹中
            }
        }

        // 压缩合同文件夹
        String zipFilePath = tempDirPath + File.separator + "合同.zip";
        FileUtil.zipFolder(Paths.get(zipFolderPath), zipFilePath);

        // URL 编码文件名
        String encodedFileName = URLEncoder.encode("合同.zip", StandardCharsets.UTF_8.toString());

        // 返回压缩文件给前端
        response.setContentType("application/zip");
        response.setHeader("Content-Disposition", "attachment; filename=\"" + encodedFileName + "\"");
        try (InputStream is = new FileInputStream(zipFilePath);
             OutputStream os = response.getOutputStream()) {
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = is.read(buffer)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
        }catch (IOException e) {
            // 处理 IOException
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "文件下载失败");
        } finally {
            // 删除临时文件夹及其内容
            FileUtil.deleteDirectory(Paths.get(tempDirPath));
        }
    }
}
